#include "aw35615_driver.h"
#include "n32g43x.h"
#include "n32g43x_i2c.h"
#include "n32g43x_rcc.h"
#include "n32g43x_gpio.h"
#include "iic.h"
#include "systick.h"

void I2C_CustomInit(void)
{
    I2C_InitType i2c1_master;
    GPIO_InitType i2c1_gpio;

    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_I2C1, ENABLE);
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
    GPIOA->POD |= (GPIO_PIN_4 | GPIO_PIN_5); // pull up pin

    /*PB8 -- SCL; PB9 -- SDA*/
    GPIO_InitStruct(&i2c1_gpio);
    i2c1_gpio.Pin = GPIO_PIN_4 | GPIO_PIN_5;
    i2c1_gpio.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
    i2c1_gpio.GPIO_Mode = GPIO_Mode_AF_OD;
    i2c1_gpio.GPIO_Pull = GPIO_Pull_Up;
    i2c1_gpio.GPIO_Alternate = GPIO_AF7_I2C1;
    i2c1_gpio.GPIO_Pull = GPIO_Pull_Up;
    GPIO_InitPeripheral(GPIOA, &i2c1_gpio);

    I2C_DeInit(I2C1);
    I2C_InitStruct(&i2c1_master);
    i2c1_master.BusMode = I2C_BUSMODE_I2C;
    i2c1_master.FmDutyCycle = I2C_FMDUTYCYCLE_2;
    i2c1_master.OwnAddr1 = 0;
    i2c1_master.AckEnable = I2C_ACKEN;
    i2c1_master.AddrMode = I2C_ADDR_MODE_7BIT;
    i2c1_master.ClkSpeed = 30000; // 30K

    I2C_Init(I2C1, &i2c1_master);
    I2C_Enable(I2C1, ENABLE);
}

AW_BOOL aw_platform_iic2_writebytes(AW_U8 port_id, AW_U8 i2c_addr, AW_U8 reg_addr, AW_U8 length, AW_U8 *data)
{
      Delay_ms(5);
    I2C_Module *I2Cx = I2C1;
    AW_U8 i;
    // ErrorStatus status;
    uint32_t timeout = I2C1_TIMEOUT;
    // 生成 START 条件
    I2C_GenerateStart(I2Cx, ENABLE);
    //  等待 EV5 事件（主设备模式标志）
    while (!I2C_CheckEvent(I2Cx, I2C_EVT_MASTER_MODE_FLAG))
    {
        if (--timeout == 0)
        {
            I2C_GenerateStop(I2Cx, ENABLE);
            printf("I2C1 write: Timeout waiting for EV5\n");
            return AW_FALSE;
        }
    }

    // 发送设备地址和写操作标志
    I2C_SendAddr7bit(I2Cx, i2c_addr, I2C_DIRECTION_SEND);

    // 等待 EV6 事件（主设备发送模式标志）
    timeout = I2C1_TIMEOUT;
    while (!I2C_CheckEvent(I2Cx, I2C_EVT_MASTER_TXMODE_FLAG))
    {
        if (--timeout == 0)
        {
            I2C_GenerateStop(I2Cx, ENABLE);
            // printf("I2C1 write: Timeout waiting for EV6\n");
            return AW_FALSE;
        }
    }

    // 发送寄存器地址
    I2C_SendData(I2Cx, reg_addr);

    // 等待 EV8 事件（主设备数据发送完成）
    timeout = I2C1_TIMEOUT;
    while (!I2C_CheckEvent(I2Cx, I2C_EVT_MASTER_DATA_SENDED))
    {
        if (--timeout == 0)
        {
            printf("I2C1 write: Timeout waiting for EV8\n");
            return AW_FALSE;
        }
    }

    // 发送数据
    for (i = 0; i < length; i++)
    {
        I2C_SendData(I2Cx, data[i]);

        // 等待 EV8 事件
        timeout = I2C1_TIMEOUT;
        while (!I2C_CheckEvent(I2Cx, I2C_EVT_MASTER_DATA_SENDED))
        {
            if (--timeout == 0)
            {
                printf("I2C1 write: Timeout waiting for EV8\n");
                return AW_FALSE;
            }
        }
    }

    // 生成 STOP 条件
    I2C_GenerateStop(I2Cx, ENABLE);
    return AW_TRUE;
}

AW_BOOL aw_platform_iic2_readbytes(AW_U8 port_id, AW_U8 i2c_addr, AW_U8 reg_addr, AW_U8 length, AW_U8 *data)
{
    Delay_ms(5);
    I2C_Module *I2Cx = I2C1;
    AW_U8 i;
    //  ErrorStatus status;
    uint32_t timeout = I2C1_TIMEOUT;

    // 生成 START 条件
    I2C_GenerateStart(I2Cx, ENABLE);
    // printf("I2C1: Sent START condition\n");
    I2C_ConfigAck(I2C1, ENABLE);
    // 等待 EV5 事件（主设备模式标志）
    while (!I2C_CheckEvent(I2Cx, I2C_EVT_MASTER_MODE_FLAG))
    {
        if (--timeout == 0)
        {
            I2C_GenerateStop(I2Cx, ENABLE);
            printf("I2C1 read: Timeout waiting for EV5\n");
            return AW_FALSE;
        }
    }

    // 发送设备地址和写操作标志
    I2C_SendAddr7bit(I2Cx, i2c_addr, I2C_DIRECTION_SEND);
    //  printf("I2C1: Sent device address for write\n");

    // 等待 EV6 事件（主设备发送模式标志）
    timeout = I2C1_TIMEOUT;
    while (!I2C_CheckEvent(I2Cx, I2C_EVT_MASTER_TXMODE_FLAG))
    {
        if (--timeout == 0)
        {
            I2C_GenerateStop(I2Cx, ENABLE);
            // printf("I2C1 read: Timeout waiting for EV6\n");
            return AW_FALSE;
        }
    }

    // 发送寄存器地址
    I2C_SendData(I2Cx, reg_addr);
    // printf("I2C1: Sent register address 0x%02X\n", reg_addr);

    // 等待 EV8 事件（主设备数据发送完成）
    timeout = I2C1_TIMEOUT;
    while (!I2C_CheckEvent(I2Cx, I2C_EVT_MASTER_DATA_SENDED))
    {
        if (--timeout == 0)
        {
            printf("I2C1 read: Timeout waiting for EV8\n");
            return AW_FALSE;
        }
    }
    // printf("I2C1: EV8 event received\n");
    // 重新生成 START 条件（重复起始）
    I2C_GenerateStart(I2Cx, ENABLE);
    // printf("I2C1: Sent repeated START condition\n");
    // 等待 EV5 事件
    timeout = I2C1_TIMEOUT;
    while (!I2C_CheckEvent(I2Cx, I2C_EVT_MASTER_MODE_FLAG))
    {
        if (--timeout == 0)
        {
            I2C_GenerateStop(I2Cx, ENABLE);
            printf("I2C1 read: Timeout waiting for EV5\n");
            return AW_FALSE;
        }
    }

    // 发送设备地址和读操作标志
    I2C_SendAddr7bit(I2Cx, i2c_addr, I2C_DIRECTION_RECV);
    //   printf("I2C1: Sent device address for read\n");

    // 等待 EV6 事件（主设备接收模式标志）
    timeout = I2C1_TIMEOUT;
    while (!I2C_CheckEvent(I2Cx, I2C_EVT_MASTER_RXMODE_FLAG))
    {
        if (--timeout == 0)
        {
            I2C_GenerateStop(I2Cx, ENABLE);
            //  printf("I2C1 read: Timeout waiting for EV6\n");
            return AW_FALSE;
        }
    }
    Delay_ms(1);
    for (i = 0; i < length; i++)
    {
        // 在读取最后一个字节之前禁用 ACK，并在读取后立即发送 STOP 条件
        if (i == (length - 1)) // 如果是最后一个字节
        {
            I2C_ConfigAck(I2Cx, DISABLE); // 发送 NACK
            data[i] = I2C_RecvData(I2Cx);
            // printf("I2C1: Received last data byte 0x%02X\n", data[i]);
            I2C_GenerateStop(I2Cx, ENABLE); // 立即发送 STOP 条件
        }
        else
        {
            I2C_ConfigAck(I2Cx, ENABLE); // 否则发送 ACK
            data[i] = I2C_RecvData(I2Cx);
            printf("I2C1: Received data byte 0x%02X\n", data[i]);
        }

        // 等待 EV7 事件（主设备数据接收完成）
        timeout = I2C1_TIMEOUT;
        while (!I2C_CheckEvent(I2Cx, I2C_EVT_MASTER_DATA_RECVD_FLAG))
        {
            if (--timeout == 0)
            {
                printf("I2C1 read: Timeout waiting for EV7\n");
                return AW_FALSE;
            }
        }
        //     printf("I2C1: EV7 event received\n");
    }

    //  printf("I2C1 read: Success\n");
    return AW_TRUE;
}

void Delay_u(uint32_t us)
{
    uint32_t cycles_per_us = 108;
    while (us--)
    {
        volatile uint32_t i = 0;
        for (i = 0; i < cycles_per_us; i++)
        {
            __NOP();
        }
    }
}

void I2C_BusRecovery(void)
{
    GPIO_InitType gpio;

    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);

    // 临时将（SDA）和（SCL）设为开漏输出
    GPIO_InitStruct(&gpio);
    gpio.Pin = GPIO_PIN_4 | GPIO_PIN_5;
    gpio.GPIO_Mode = GPIO_Mode_Out_OD;
    gpio.GPIO_Pull = GPIO_Pull_Up;
    gpio.GPIO_Current = GPIO_DC_4mA;
    GPIO_InitPeripheral(GPIOA, &gpio);

    // 手动拉高 SCL 和 SDA
    GPIO_SetBits(GPIOA, GPIO_PIN_4 | GPIO_PIN_5);
    Delay_u(10);

    // 产生 9 个 SCL 脉冲，释放 SDA
    int i = 0;
    for (i = 0; i < 9; i++)
    {
        GPIO_SetBits(GPIOA, GPIO_PIN_4); // SCL高
        Delay_u(5);
        GPIO_ResetBits(GPIOA, GPIO_PIN_4); // SCL低
        Delay_u(5);
    }
    // 恢复为 I2C 功能
    I2C_CustomInit();
}

